home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / 8bit / language / stacktst.txt < prev    next >
Internet Message Format  |  1995-04-22  |  12KB

  1. From hufnagel Thu Dec  1 09:16:15 1994 
  2. Return-Path: <hufnagel> 
  3. Received: by zippy.sonoma.EDU (4.1/SMI-4.0) 
  4.     id AA23081; Thu, 1 Dec 94 09:16:14 PST 
  5. Date: Thu, 1 Dec 94 09:16:14 PST 
  6. From: hufnagel (Michael Hufnagel) 
  7. Message-Id: <9412011716.AA23081@zippy.sonoma.EDU> 
  8. To: kendrick 
  9. Subject: here 
  10. Status: RO 
  11.  
  12. >From KENDRICK@sonoma.edu Thu Dec  1 08:26:00 1994 
  13. To: bob@zippy.sonoma.EDU, LYLEM@sonoma.edu, HUFNAGEL@sonoma.edu, 
  14.         comp-sys-atari-8bit@cs.utexas.edu 
  15. Subject: Recursion in Action!  This seems to do it!  (STACKTST.ACT/.C/.BAS) 
  16.  
  17. The following file is the C code I first came up with when I was  
  18. thinking of how to go about adding a local-variable stack to Action! 
  19. so that PROCedures and FUNCtions can be made to do recursion. 
  20.  
  21. I tested it out in Think C++ on a Macintosh but didn't trust it  
  22. since, well, C handles this by itself, so all I could be doing is 
  23. wasting memory!  But never fear, two files follow this: 
  24.  
  25. -----------------begin-stacktst.c---------------------- 
  26. /* StackTst.c: Stack Test program for adding recursion to Action! */ 
  27.  
  28. #include "stdio.h" 
  29.  
  30. int sp; 
  31. int stack[1024]; 
  32.  
  33. void overflow() 
  34.     printf("Overflow\n"); 
  35.  
  36. void underflow() 
  37.     printf("Underflow\n"); 
  38.  
  39. void init() 
  40.     sp=0; 
  41.  
  42. void push(int x) 
  43.     stack[sp]=x; 
  44.     sp=sp+1; 
  45.     if (sp>1024) 
  46.         overflow(); 
  47.  
  48. int pop() 
  49.     if (sp==0) 
  50.         underflow(); 
  51.     else 
  52.     { 
  53.         sp=sp-1; 
  54.         return(stack[sp]); 
  55.     } 
  56.  
  57. /* -- */ 
  58.  
  59. int factorial(int n) 
  60.     int m; 
  61.  
  62.     if (n<=1) 
  63.         m=1; 
  64.     else 
  65.     { 
  66.         push(n); 
  67.         m=factorial(n-1); 
  68.         n=pop(); 
  69.         m=m*n; 
  70.     } 
  71.     return m; 
  72.  
  73. void main() 
  74.     prinf("6!=%d\n",factorial(6)); 
  75.  
  76. /* By Bill Kendrick 11/29/1994 */  /* See STACKTST.ACT... */ 
  77.  
  78. -----------end---------- 
  79.  
  80. Well, since I didn't trust it, I started writing another text program 
  81. in QBASIC on an IBM.  Of course, at first I started out writing the thing 
  82. with "SUBS" and "FUNCTIONS"!  Duh!  QBASIC probably uses a stack for 
  83. local variables too!  So I started over and just used GOSUBS and passed 
  84. variables to my GOSUB'd functions via "x" and "n" variables.  The code 
  85. looks much more drawn out than it needs to be in a higher level language, 
  86. but for you Atari BASIC and TurboBASIC XL users, you may find this useful 
  87. nonetheless.  BTW: This seems to work too! :) 
  88.  
  89. ----------begin-stacktst.bas------- 
  90. 1 ' StackTst.Bas 
  91. 2 ' by Bill Kendrick 11/29/1994 
  92. 3 ' Test of StackTst.c code in (Q)BASIC without using real 
  93. 4 ' FUNCs. 
  94.  
  95. 5 DIM stack(100) 
  96. 6 GOTO 1000 
  97.  
  98. 10 ' push 
  99. 11 stack(sp) = x 
  100. 12 sp = sp + 1 
  101. 13 RETURN 
  102.  
  103. 20 ' pop 
  104. 21 sp = sp - 1 
  105. 22 x = stack(sp) 
  106. 23 RETURN 
  107.  
  108. 100 ' factorial 
  109. 101 IF n <= 1 THEN 
  110. 102   m = 1 
  111. 103 ELSE 
  112. 104   x = n      ' \ push(n) 
  113. 105   GOSUB 10   ' / 
  114. 106   n = n - 1      ' \ 
  115. 107   GOSUB 100      '  > m=factorial(n-1) 
  116. 108   m = x          ' / 
  117. 109   GOSUB 20   ' \ m=pop() 
  118. 110   n = x      ' / 
  119. 111   m = m * n 
  120. 112 END IF 
  121. 113 x = m        ' return(x) 
  122. 114 RETURN 
  123.  
  124. 1000 ' main 
  125. 1001 n = 6       ' \ 
  126. 1002 GOSUB 100   '  > print factorial(6) 
  127. 1003 PRINT x     ' / 
  128. 1004 END 
  129.  
  130. ----------end---------- 
  131.  
  132. Finally, after this last sucessful trial, I came up with the following 
  133. Action! code, based on the C code above.  I ran it, got "720" as a 
  134. result (6!=720), screamed and jumped up and down; proceeded to tell the 
  135. person on the other line what had just happened (giving her a breif 
  136. description of recursion and factorial), then apologized and asked her 
  137. to repeat what she was saying a moment before. <grin>  ANYWAYS, I hadn't 
  138. booted any DOS with the thing and was planning on using SIO2PC's Print-Thru 
  139. and Atari's built in P:rinter device to make a copy of the thing as a file 
  140. on my PC, but accidentally hit "D" for DOS instead of "E" for editor in 
  141. Action!'s monitor and poof it was gone and I was enjoying the OS's Self-Test 
  142. menu <sigh>.  The following is obviously not my ORIGINAL code <grin>, 
  143. AND IS NOT IDENTICAL to the C code!  This gives you a menu letting you 
  144. chose between FACTORIAL, FIBONACCI, and ACKERMANN recursive functions. 
  145. ACKERMANN has not been tested, and when doing FACTORIAL and FIBONACCI, 
  146. remember that I used INTs, so when it calculates values over 32767 or 
  147. below -32768, the variable will have over-/under-flowed and answers will 
  148. be wrong, but hell, at least it works for INTs! :) 
  149.  
  150. ----begin-stacktst.act----- 
  151. ; STACKTST.ACT 
  152.  
  153. ; Local variable stack handler for 
  154. ; Action! test program. 
  155.  
  156. ; By Bill Kendrick  11/29/1994 
  157.  
  158. DEFINE STACKSIZE="200" 
  159. DEFINE LARGESTTYPE="CARD"             ; Type mismatches don't create errors, 
  160.                                       ; so use the largest (2-bytes) available 
  161.  
  162. CARD SP                               ; Stack pointer 
  163. LARGESTTYPE ARRAY STACK(STACKSIZE)    ; Stack storage space 
  164.  
  165. PROC OVERFLOW() 
  166.   PRINTE("OVERFLOW")                  ; Display error 
  167.   PRINT("STACK POINTER ABOVE ") 
  168.   PRINTCE(STACKSIZE) 
  169.   BREAK()                             ; and abort program 
  170. RETURN 
  171.  
  172. PROC UNDERFLOW() 
  173.   PRINTE("UNDERFLOW") 
  174.   PRINTE("STACK POINTER BELOW 0") 
  175.   BREAK() 
  176. RETURN 
  177.  
  178. PROC INIT()                           ; All we need to do here is reset the 
  179.   SP=0                                ; stack pointer either before a 
  180. RETURN                                ; recursive function's called or at 
  181.                                       ; program start. 
  182.  
  183. PROC PUSH(LARGESTTYPE V) 
  184.   STACK(SP)=V                         ; Store value 
  185.   SP=SP+1                             ; Increment stack pointer 
  186.   IF SP>=STACKSIZE-2 THEN             ; Test for overflow 
  187.     OVERFLOW() 
  188.   FI 
  189. RETURN 
  190.  
  191. LARGESTTYPE FUNC POP() 
  192.   LARGESTTYPE V 
  193.  
  194.   IF SP=0 THEN                        ; Test for possible underflow 
  195.     UNDERFLOW() 
  196.   ELSE 
  197.     SP=SP-1                           ; Decrement stack pointer 
  198.     V=STACK(SP)                       ; Retrieve value 
  199.   FI 
  200. RETURN(V) 
  201.  
  202. ; ---------------------------------- 
  203.  
  204. INT FUNC FACTORIAL(INT N) 
  205.   INT M                               ; Temporary variable; its value is 
  206.                                       ; RETURN'd 
  207.   IF N<=1 THEN                        ; 1!=1.. 
  208.     M=1 
  209.   ELSE 
  210.     PUSH(N)                           ; Push before recursion 
  211.     M=FACTORIAL(N-1)                  ; Call function for N-1, store in M 
  212.     N=POP()                           ; (Get old N after last recursion was 
  213.                                       ; returned from) 
  214.     M=M*N                             ; Multiply.. 
  215.   FI 
  216. RETURN(M)                             ; ..and return value 
  217.  
  218. INT FUNC ACKERMANN(INT X,Y) 
  219.   INT R 
  220.  
  221.   R=0 
  222.   IF X=0 AND Y>=0 THEN 
  223.     R=Y+1 
  224.   ELSEIF Y=0 AND X>0 THEN 
  225.     PUSH(X) 
  226.     PUSH(Y) 
  227.     R=ACKERMANN(X-1,1) 
  228.     Y=POP() 
  229.     X=POP() 
  230.   ELSE 
  231.     PUSH(X) 
  232.     PUSH(Y) 
  233.     R=ACKERMANN(X,Y-1) 
  234.     Y=POP() 
  235.     X=POP() 
  236.     PUSH(X) 
  237.     PUSH(Y) 
  238.     R=ACKERMANN(X-1,R) 
  239.     Y=POP() 
  240.     X=POP() 
  241.   FI 
  242. RETURN(R) 
  243.  
  244. INT FUNC FIBONACCI(INT N) 
  245.   INT R1,R2                           ; Temporary variable; its value is 
  246.                                       ; RETURN'd 
  247.   IF N=0 OR N=1 THEN                  ; FIB(0)=0,FIB(1)=1 
  248.     R1=N 
  249.     R2=0 
  250.   ELSE 
  251.     PUSH(N)                           ; Push before recursion 
  252.     R1=FIBONACCI(N-1)                 ; Call function for N-1, store in M 
  253.     N=POP() 
  254.     PUSH(R1)                          ; Push before recursion 
  255.     PUSH(N)                           ; Push before recursion 
  256.     R2=FIBONACCI(N-2)                 ; Call function for N-1, store in M 
  257.     N=POP() 
  258.     R1=POP()                          ; (Get old N after last recursion was 
  259.                                       ; returned from) 
  260.   FI 
  261.   R1=R1+R2 
  262. RETURN(R1)                            ; ..and return value 
  263.  
  264. PROC MAIN() 
  265.   INT A,B,RESULT 
  266.  
  267.   INIT()                              ; Init Stack 
  268.   PRINTE("1=FACTORIAL") 
  269.   PRINTE("2=ACKERMANN") 
  270.   PRINTE("3=FIBONACCI") 
  271.   A=INPUTB() 
  272.   IF A=1 THEN 
  273.     PRINTE("Factorial")                 ; Title/instructions: 
  274.     PUTE()                              ; (blank line (PUT End Of Line)) 
  275.     PRINTE("Enter 'A' and I will") 
  276.     PRINTE("show you 'A!'.") 
  277.     PUTE() 
  278.     PRINTE("Enter '0' to quit.") 
  279.     DO 
  280.       PUTE() 
  281.       PRINT(" A=")                      ; Prompt (no EOL after) 
  282.       A=INPU